﻿using H.Nets;
using System;
using System.Net.Sockets;
using System.Threading;

namespace H.Net.Nets
{
    /// <summary>
    /// 表示一个TCP客户端
    /// </summary>
    public class HTcpClient : AbstractTcpClient
    {

        /// <summary>
        /// 用于表示客户端的字符串,修改之后,服务端的实例也会自动修改
        /// </summary>
        public override string Identifier
        {
            get => _Identifier ?? _Socket?.LocalEndPoint.ToString();
            set
            {
                if (Identifier != value)
                {
                    Send(HFrameType.IDENTIFY, value);
                    _Identifier = value;
                    NotifyClientRename(Identifier, value);
                }
            }
        }

        /// <summary>
        /// 客户端是否可用
        /// </summary>
        public override bool IsValid => true;

        #region 内部字段
        /// <summary>
        /// 当前可用的消息ID
        /// </summary>
        private int _CurTopicID = 1;

        /// <summary>
        /// 服务器主机名称
        /// </summary>
        private readonly string _HostName;

        /// <summary>
        /// 服务器主机端口
        /// </summary>
        private readonly int _Port;

        #endregion

        /// <summary>
        /// 初始化一个的客户端
        /// </summary>
        /// <param name="hostName"></param>
        /// <param name="port"></param>
        public HTcpClient(string hostName, int port)
            : base(null)
        {
            _HostName = hostName;
            _Port = port;
        }

        /// <summary>
        /// 创建一个新的话题ID
        /// </summary>
        /// <returns>返回一个新的话题ID</returns>
        public override int CreateTopic()
        {
            return _CurTopicID = _CurTopicID % int.MaxValue + 1;
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        public override void Connect()
        {
            if (_Socket == null || !_Socket.Connected)
            {
                _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                {
                    ReceiveBufferSize = 1 << 15
                };

                try
                {
                    _Socket.Connect(_HostName, _Port);
                    NotifyChangeStatus(true);
                    _FrameStream = new HFrameStream(_Socket);
                    StartRead(CancellationToken.None);
                }
                catch (SocketException err)
                {
                    NotifyChangeStatus(false);
                    throw err;
                }
                catch (Exception err)
                {
                    NotifyChangeStatus(false);
                    Console.WriteLine(err);
                }
                //_Socket.BeginConnect(_HostName, _Port, iResult =>
                // {
                //     try
                //     {
                //         _Socket.EndConnect(iResult);
                //         OnChangeStatus(true);
                //         StartRead();
                //     }
                //     catch (Exception err)
                //     {
                //         Console.WriteLine(err);
                //     }
                // }, null);
            }
        }
    }
}
